package com.nbx.app.neheport.render;

import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;
import javax.microedition.khronos.opengles.GL11;

import com.nbx.app.neheport.R;
import com.nbx.library.glutes.util;

import android.content.Context;
import android.graphics.Bitmap;
import android.opengl.GLU;
import android.opengl.GLUtils;
import android.view.KeyEvent;
import android.view.MotionEvent;

public class Render16 extends RenderBase {
    
    private float rotx = 0.0f;
    private float roty = 0.0f;
    
    private float speed = 2.0f;
    
    private float z = -5.0f;
    
    private int mTextureID[];
    
    private int filter = 0;
    
    
    private float box[] = {
            // FRONT
            -0.5f, -0.5f,  0.5f,
             0.5f, -0.5f,  0.5f,
            -0.5f,  0.5f,  0.5f,
             0.5f,  0.5f,  0.5f,
            // BACK
            -0.5f, -0.5f, -0.5f,
            -0.5f,  0.5f, -0.5f,
             0.5f, -0.5f, -0.5f,
             0.5f,  0.5f, -0.5f,
            // LEFT
            -0.5f, -0.5f,  0.5f,
            -0.5f,  0.5f,  0.5f,
            -0.5f, -0.5f, -0.5f,
            -0.5f,  0.5f, -0.5f,
            // RIGHT
             0.5f, -0.5f, -0.5f,
             0.5f,  0.5f, -0.5f,
             0.5f, -0.5f,  0.5f,
             0.5f,  0.5f,  0.5f,
            // TOP
            -0.5f,  0.5f,  0.5f,
             0.5f,  0.5f,  0.5f,
             -0.5f,  0.5f, -0.5f,
             0.5f,  0.5f, -0.5f,
            // BOTTOM
            -0.5f, -0.5f,  0.5f,
            -0.5f, -0.5f, -0.5f,
             0.5f, -0.5f,  0.5f,
             0.5f, -0.5f, -0.5f,
    };

    private float texCoords[] = {
            // FRONT
             0.0f, 0.0f,
             1.0f, 0.0f,
             0.0f, 1.0f,
             1.0f, 1.0f,
            // BACK
             1.0f, 0.0f,
             1.0f, 1.0f,
             0.0f, 0.0f,
             0.0f, 1.0f,
            // LEFT
             1.0f, 0.0f,
             1.0f, 1.0f,
             0.0f, 0.0f,
             0.0f, 1.0f,
            // RIGHT
             1.0f, 0.0f,
             1.0f, 1.0f,
             0.0f, 0.0f,
             0.0f, 1.0f,
            // TOP
             0.0f, 0.0f,
             1.0f, 0.0f,
             0.0f, 1.0f,
             1.0f, 1.0f,
            // BOTTOM
             1.0f, 0.0f,
             1.0f, 1.0f,
             0.0f, 0.0f,
             0.0f, 1.0f
    };
    
    boolean   gp;
    private int fogMode[]= { GL11.GL_EXP, GL11.GL_EXP2, GL11.GL_LINEAR };
    private int fogfilter= 0;
    private float fogColor[]= {0.5f, 0.5f, 0.5f, 1.0f};
   
    private FloatBuffer mCubeVetexBuffer;
    private FloatBuffer mCubeTexBuffer;
    
    public Render16(Context context) {
        super(context);
    }

    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        mCubeVetexBuffer = util.createFloatBuffer(box);
        mCubeTexBuffer = util.createFloatBuffer(texCoords);
        
        loadBitmapTex(gl);
        
        gl.glEnable(GL10.GL_TEXTURE_2D); // Enable Texture Mapping ( NEW )
        gl.glShadeModel(GL10.GL_SMOOTH); // Enable Smooth Shading
        //gl.glClearColor(0.0f, 0.0f, 0.0f, 0.5f); // Black Background


        gl.glClearColor(0.5f,0.5f,0.5f,1.0f);
        gl.glFogx(GL10.GL_FOG_MODE, fogMode[fogfilter]);
        gl.glFogfv(GL10.GL_FOG_COLOR, fogColor, 0);
        gl.glFogf(GL10.GL_FOG_DENSITY, 0.35f);
        gl.glHint(GL10.GL_FOG_HINT, GL10.GL_DONT_CARE);
        gl.glFogf(GL10.GL_FOG_START, 1.0f);
        gl.glFogf(GL10.GL_FOG_END, 5.0f);
    	gl.glEnable(GL10.GL_FOG);
        
        gl.glClearDepthf(1.0f); // Depth Buffer Setup
        gl.glEnable(GL10.GL_DEPTH_TEST); // Enables Depth Testing
        gl.glDepthFunc(GL10.GL_LEQUAL); // The Type Of Depth Testing To Do
        //gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_NICEST);  // Really Nice Perspective Calculations
    }
    
    public void onDrawFrame(GL10 gl) {        
        
        gl.glClear(GL10.GL_COLOR_BUFFER_BIT | GL10.GL_DEPTH_BUFFER_BIT); // Clear Screen And Depth Buffer
        gl.glLoadIdentity();
        
        gl.glFogx(GL10.GL_FOG_MODE, fogMode[fogfilter]);
        // Cube
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
        
        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]);
        
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, mCubeVetexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mCubeTexBuffer);

        gl.glPushMatrix();
        gl.glTranslatef(0.0f, 0.0f, z);
        gl.glRotatef(rotx, 1, 0, 0);
        gl.glRotatef(roty, 0, 1, 0);
        
        // FRONT AND BACK
        //gl.glNormal3f(0.0f, 0.0f, 1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 0, 4);
        //gl.glNormal3f(0.0f, 0.0f, -1.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 4, 4);

        // LEFT AND RIGHT
        //gl.glNormal3f(-1.0f, 0.0f, 0.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 8, 4);
        //gl.glNormal3f(1.0f, 0.0f, 0.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 12, 4);

        // TOP AND BOTTOM
        //gl.glNormal3f(0.0f, 1.0f, 0.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 16, 4);
        //gl.glNormal3f(0.0f, -1.0f, 0.0f);
        gl.glDrawArrays(GL10.GL_TRIANGLE_STRIP, 20, 4);
   
        gl.glPopMatrix();

        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        rotx += (speed + 0.1f);
        roty += speed;
    }

    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0,0,width,height);                       // Reset The Current Viewport

        gl.glMatrixMode(GL10.GL_PROJECTION);                        // Select The Projection Matrix
        gl.glLoadIdentity();                                   // Reset The Projection Matrix

        // Calculate The Aspect Ratio Of The Window
        GLU.gluPerspective(gl, 45.0f,(float)width/(float)height,0.1f,100.0f);

        gl.glMatrixMode(GL10.GL_MODELVIEW);                         // Select The Modelview Matrix
        gl.glLoadIdentity();   
    }
    
    private void loadBitmapTex(GL10 gl){
        mTextureID = new int[1];
        gl.glGenTextures(1, mTextureID, 0);

        Bitmap bmp = util.getTextureFromBitmapResource(mContext, R.drawable.crate);

        gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID[0]);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MAG_FILTER,GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D,GL10.GL_TEXTURE_MIN_FILTER,GL10.GL_NEAREST);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bmp, 0);
        
        bmp.recycle();

        return;
    }
    
    @Override
    public boolean handleTouchEvent(MotionEvent event) {
        if(event.getAction() == MotionEvent.ACTION_UP){
        	fogfilter ++;
            if(fogfilter == 3){
            	fogfilter = 0;
            }
            return true;
        }
        return false;
    }    
    
    @Override
    public boolean handleKeyEvent(int keyCode, KeyEvent event) {
        if (event.getAction() == KeyEvent.ACTION_UP) {

            switch (keyCode) {
            case KeyEvent.KEYCODE_DPAD_UP: {
                z -= 2.0f;
                return true;
            }
            case KeyEvent.KEYCODE_DPAD_DOWN: {
                z += 2.0f;
                return true;
            }
            case KeyEvent.KEYCODE_DPAD_LEFT: {
                if (speed > 0.1f) {
                    speed -= 0.1f;
                }
                return true;
            }
            case KeyEvent.KEYCODE_DPAD_RIGHT: {
                speed += 0.1f;
                return true;
            }
            }
        }
        return false;
    }
}
